package cn.genmer.skywalking.plugins.springmvc;

import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.EnhanceContext;
import org.apache.skywalking.apm.agent.core.plugin.PluginException;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.StaticMethodsInterceptV2Point;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;

import static net.bytebuddy.matcher.ElementMatchers.*;

public class ApiControllerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

    public static final String SPRING_MVC_ENHANCE_CLASS = "org.springframework.web.bind.annotation.RequestMapping";
    public static final String SPRING_MVC_ENHANCE_INTERCEPTOR = "cn.genmer.skywalking.plugins.springmvc.SpringMVCParamsInterceptor";

    @Override
    protected ClassMatch enhanceClass() {
        System.out.println("[插件定义] classloader=" + this.getClass().getClassLoader());

        // 精确匹配目标类
        System.out.println("[SkyWalking] enhanceClass...: "+NameMatch.byName("com.zto56.gis.web.controller.ApiController").getClassName());

        return NameMatch.byName("com.zto56.gis.web.controller.ApiController");
    }

    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return new ConstructorInterceptPoint[0];
    }


    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        System.out.println("[SkyWalking] getInstanceMethodsInterceptPoints...:" + named("addressAnalysis"));
        return new InstanceMethodsInterceptPoint[]{
                new InstanceMethodsInterceptPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
                        // 精确匹配目标方法
                        // return named("addressAnalysis");
                        return isPublic()
                                .and(not(named("getSkyWalkingDynamicField")))
                                .and(not(named("setSkyWalkingDynamicField")))
                                .and(not(named("equals")))
                                .and(not(named("hashCode")))
                                .and(not(named("toString")));
                    }

                    @Override
                    public String getMethodsInterceptor() {
                        return SPRING_MVC_ENHANCE_INTERCEPTOR;
                    }

                    @Override
                    public boolean isOverrideArgs() {
                        return false;
                    }
                }
        };
    }


}
